package cn.itcast.hiss.process.activiti.multilnstance;

import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.HistoryService;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ExecutionEntityManager;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.task.Task;

import java.util.List;

/**
 * 删除多实例，并流转到驳回节点
 */
public class JumpMultiInstanceExecutionCmd implements Command {

    // 当前办理人的任务
    Task task;
    // 要流转的线
    SequenceFlow sequenceFlow;

    public JumpMultiInstanceExecutionCmd(Task task, SequenceFlow sequenceFlow) {
        this.task = task;
        this.sequenceFlow = sequenceFlow;
    }

    @Override
    public Object execute(CommandContext commandContext) {
        // 删除多实例：就是需要删除act_ru_execution、act_ru_task中的数据
        ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
        String executionId = task.getExecutionId();
        // 查询当前任务对应的Execution信息
        ExecutionEntity executionEntity = executionEntityManager.findById(executionId);
        // 查询当前任务的父Execution信息
        ExecutionEntity parent = getMultiInstnceRootExecution(executionEntity);
        // 查询当前父Execution的所有子Execution数据
        List<ExecutionEntity> childExecutions = executionEntityManager.findChildExecutionsByParentExecutionId(parent.getId());
        // 获取历史查询API
        HistoryService historyService = commandContext.getProcessEngineConfiguration().getHistoryService();
        // 删除所有的子execution数据
        for(ExecutionEntity childExecution : childExecutions){
            // 删除当前execution的子数据
            executionEntityManager.deleteChildExecutions(childExecution,"Delete for jump");
            // 删除当前execution以及关联数据，可以简单的理解成他的关联数据有act_ru_task表中的数据
            executionEntityManager.deleteExecutionAndRelatedData(childExecution,"Delete for jump");
            // 删除历史表中的任务数据，防止前端显示
            List<TaskEntity> tasks = childExecution.getTasks();
            if(task!=null){
                for(TaskEntity taskEntity : tasks){
                    historyService.deleteHistoricTaskInstance(taskEntity.getId());
                }
            }
        }
        // 删除MIRoot的execution
        executionEntityManager.deleteExecutionAndRelatedData(parent,"Delete for jump");

        // 手动流转到下一个节点，既驳回节点
        ExecutionEntity root = parent.getParent();
        if(root!=null){
            ExecutionEntity childExecution = executionEntityManager.createChildExecution(root);
            childExecution.setActive(true);
            childExecution.setScope(false);
            childExecution.setCurrentFlowElement(sequenceFlow.getTargetFlowElement());
            commandContext.getAgenda().planContinueProcessOperation(childExecution); // 手动流转流程到目标节点
        }

        return null;
    }

    /**
     * 递归查找当前多实例Execution的父Execution信息
     * @param executionEntity
     * @return
     */
    private ExecutionEntity getMultiInstnceRootExecution(ExecutionEntity executionEntity) {
        ExecutionEntity parent = executionEntity.getParent();
        if(parent!=null){
            if(parent.isMultiInstanceRoot()){
                return parent;
            }else{
                return getMultiInstnceRootExecution(parent);
            }
        }
        return null;
    }
}
